package co.mobiwise.playerview;

import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.Path;
import ohos.agp.utils.Color;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;
import ohos.multimodalinput.event.TouchEvent;

public class PlaypauseView extends Component implements OnPlayPauseToggleListener,Component.DrawTask,
        Component.EstimateSizeListener, Component.TouchEventListener {

    private int mWidth;
    private int mHeight;
    private final Path mLeftPauseBar = new Path();
    private final Path mRightPauseBar = new Path();
    private final Paint mPaint = new Paint();
    private final RectFloat mBounds = new RectFloat();
    private static float mPauseBarWidth;
    private static float mPauseBarHeight;
    private static float mPauseBarDistance;


    public void initPlayPause(){
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.FILL_STYLE);
        mPaint.setColor(Color.WHITE);
        mPauseBarWidth = 24;
        mPauseBarHeight = 72;
        mPauseBarDistance = 20;
        startAnimator();
    }
    public PlaypauseView(Context context) {
        super(context);
        // 获取屏幕的宽高度、中心点坐标，调用onEstimateSize方法
        setEstimateSizeListener(this);
        // 添加绘制任务，调用onDraw方法
        addDrawTask(this);
        // 调用onTouchEvent方法
        setTouchEventListener(this);
        initPlayPause();
    }

    public PlaypauseView(Context context, AttrSet attrSet) {
        super(context, attrSet);
        // 获取屏幕的宽高度、中心点坐标，调用onEstimateSize方法
        setEstimateSizeListener(this);
        // 添加绘制任务，调用onDraw方法
        addDrawTask(this);
        // 调用onTouchEvent方法
        setTouchEventListener(this);
        initPlayPause();
    }

    public PlaypauseView(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        // 获取屏幕的宽高度、中心点坐标，调用onEstimateSize方法
        setEstimateSizeListener(this);
        // 添加绘制任务，调用onDraw方法
        addDrawTask(this);
        // 调用onTouchEvent方法
        setTouchEventListener(this);

    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        drawPlayPause(canvas);
    }

    @Override
    public boolean onEstimateSize(int i, int i1) {
        mWidth = EstimateSpec.getSize(i);
        mHeight = EstimateSpec.getSize(i1);
        int minSide = Math.min(mWidth, mHeight);
        mWidth = minSide;
        mHeight = minSide;
        setEstimatedSize(
                EstimateSpec.getChildSizeWithMode(mWidth, mHeight, EstimateSpec.PRECISE),
                EstimateSpec.getChildSizeWithMode(mWidth, mHeight, EstimateSpec.PRECISE)
        );
        return true;
    }

    @Override
    public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
        float x = touchEvent.getPointerPosition(touchEvent.getIndex()).getX();
        float y = touchEvent.getPointerPosition(touchEvent.getIndex()).getY();

        switch (touchEvent.getAction()) {
            case TouchEvent.PRIMARY_POINT_DOWN: {
                return true;
            }
            case TouchEvent.PRIMARY_POINT_UP: {
                if(animatorVal.isRunning()){
                    return true;
                }
                onToggled();
               startAnimator();
            }
            break;

            default: break;
        }

        return true;
    }
    /**
     * Linear interpolate between a and b with parameter t.
     */
    private static float lerp(float a, float b, float t) {
        return a + (b - a) * t;
    }
    private boolean mIsPlay;
    float mProgress=0;
    public void drawPlayPause(Canvas canvas){
        mLeftPauseBar.rewind();
        mRightPauseBar.rewind();

        // The current distance between the two pause bars.
        final float barDist = lerp(mPauseBarDistance, 0, mProgress);
        // The current width of each pause bar.
        final float barWidth = lerp(mPauseBarWidth, mPauseBarHeight / 2f, mProgress);
        // The current position of the left pause bar's top left coordinate.
        final float firstBarTopLeft = lerp(0, barWidth, mProgress);
        // The current position of the right pause bar's top right coordinate.
        final float secondBarTopRight = lerp(2 * barWidth + barDist, barWidth + barDist, mProgress);

        // Draw the left pause bar. The left pause bar transforms into the
        // top half of the play button triangle by animating the position of the
        // rectangle's top left coordinate and expanding its bottom width.
        mLeftPauseBar.moveTo(0, 0);
        mLeftPauseBar.lineTo(firstBarTopLeft, -mPauseBarHeight);
        mLeftPauseBar.lineTo(barWidth, -mPauseBarHeight);
        mLeftPauseBar.lineTo(barWidth, 0);
        mLeftPauseBar.close();

        // Draw the right pause bar. The right pause bar transforms into the
        // bottom half of the play button triangle by animating the position of the
        // rectangle's top right coordinate and expanding its bottom width.
        mRightPauseBar.moveTo(barWidth + barDist, 0);
        mRightPauseBar.lineTo(barWidth + barDist, -mPauseBarHeight);
        mRightPauseBar.lineTo(secondBarTopRight, -mPauseBarHeight);
        mRightPauseBar.lineTo(2 * barWidth + barDist, 0);
        mRightPauseBar.close();

        canvas.save();

        // Translate the play button a tiny bit to the right so it looks more centered.
        canvas.translate(lerp(0, mPauseBarHeight / 8f, mProgress), 0);

        // (1) Pause --> Play: rotate 0 to 90 degrees clockwise.
        // (2) Play --> Pause: rotate 90 to 180 degrees clockwise.
        final float rotationProgress = mIsPlay ? 1 - mProgress : mProgress;
        final float startingRotation = mIsPlay ? 90 : 0;
        canvas.rotate(lerp(startingRotation, startingRotation + 90, rotationProgress), mWidth / 2f,
                mHeight / 2f);

        // Position the pause/play button in the center of the drawable's bounds.
        canvas.translate(mWidth / 2f - ((2 * barWidth + barDist) / 2f),
                mHeight / 2f + (mPauseBarHeight / 2f));

        // Draw the two bars that form the animated pause/play button.
        canvas.drawPath(mLeftPauseBar, mPaint);
        canvas.drawPath(mRightPauseBar, mPaint);

        canvas.restore();
    }

    // 动画
    private AnimatorValue animatorVal = new AnimatorValue();
    // 动画时长
    final long animatorDuration = 200L;

    private void startAnimator() {
        animatorVal.setCurveType(Animator.CurveType.DECELERATE);
        animatorVal.setDuration(animatorDuration);
        animatorVal.setValueUpdateListener((AnimatorValue animatorValue, float value) -> {
            if(mIsPlay){
                //1->0
                mProgress=1-value;
                if(mProgress==0){
                    mIsPlay=!mIsPlay;
                }
            }else{
                //0->1
                mProgress=value;
                if(mProgress==1){
                    mIsPlay=!mIsPlay;
                }
            }

            invalidate();

        });
        stateChangedListener(animatorVal);
        animatorVal.start();
    }

    private void stateChangedListener(AnimatorValue animatorValue) {
        animatorValue.setStateChangedListener(new Animator.StateChangedListener() {
            @Override
            public void onStart(Animator animator) {

            }

            @Override
            public void onStop(Animator animator) {
            }

            @Override
            public void onCancel(Animator animator) {
            }

            @Override
            public void onEnd(Animator animator) {
                animator.release();
            }

            @Override
            public void onPause(Animator animator) {
            }

            @Override
            public void onResume(Animator animator) {
            }
        });
    }
    MusicPlayerView musicPlayerView;
    public void setMusicPlayerView(MusicPlayerView musicPlayerView){
        this.musicPlayerView=musicPlayerView;
    }
    @Override
    public void onToggled() {
        if(musicPlayerView!=null){
            if(mIsPlay){
                musicPlayerView.start();
            }else{
                musicPlayerView.stop();
            }

        }
    }
}
